﻿using Admin.NET.Core.Btms;

namespace Admin.NET.Application.Service;
public class XieYiYiYuanChuKuService : IDynamicApiController
{
    protected readonly SqlSugarRepository<InvBloodInfo> _repInvBloodInfo;
    protected readonly SqlSugarRepository<InvOtherOutStorageMaster> _repInvOtherOutStorageMaster;
    protected readonly SqlSugarRepository<InvOtherOutStorageDetail> _repInvOtherOutStorageDetail;
    protected readonly SqlSugarRepository<InvKuCun> _kuCun;
    protected readonly SqlSugarRepository<BasXueYeChanPin> _xueYeChanPin;
    protected readonly SqlSugarRepository<BasXueYePinZhong> _xueYePinZhong;
    protected readonly SqlSugarRepository<SysOrg> _sysOrg;
    protected readonly SqlSugarRepository<BasBloodProduct> _basBloodProduct;
    protected readonly SqlSugarRepository<BasBloodVariety> _basBloodVariety;

    private readonly SqlSugarRepository<BasYueXueYuJing> _basYueXueYuJing;
    private readonly SqlSugarRepository<BasEnum> _basEnum;


    public XieYiYiYuanChuKuService(SqlSugarRepository<InvBloodInfo> repInvBloodInfo,
        SqlSugarRepository<InvOtherOutStorageMaster> repInvOtherOutStorageMaster,
        SqlSugarRepository<InvOtherOutStorageDetail> repInvOtherOutStorageDetail,
        SqlSugarRepository<InvKuCun> kucun,
        SqlSugarRepository<BasXueYeChanPin> xueYeChanPin,
        SqlSugarRepository<BasXueYePinZhong> xueYePinZhong,
        SqlSugarRepository<SysOrg> sysOrg,
        SqlSugarRepository<BasBloodProduct> basBloodProduct,
        SqlSugarRepository<BasBloodVariety> basBloodVariety,
        SqlSugarRepository<BasEnum> basEnum,
         SqlSugarRepository<BasYueXueYuJing> basYueXueYuJing
        )
    {
        _repInvBloodInfo = repInvBloodInfo;
        _repInvOtherOutStorageMaster = repInvOtherOutStorageMaster;
        _repInvOtherOutStorageDetail = repInvOtherOutStorageDetail;
        _kuCun = kucun;
        _xueYeChanPin = xueYeChanPin;
        _xueYePinZhong = xueYePinZhong;
        _sysOrg = sysOrg;
        _basBloodProduct = basBloodProduct;
        _basBloodVariety = basBloodVariety;
        _basEnum = basEnum;
        _basYueXueYuJing = basYueXueYuJing;
    }


    public async Task<SqlSugarPagedList<InvBloodInfo>> InvBlood(BaseKeywordPageInput input)
    {
        var entityList = await _repInvBloodInfo.AsQueryable().OrderByDescending(it => it.Id).ToPagedListAsync(input.Page, input.PageSize);

        return entityList;
    }

    //查询列表协议医院出库列表
    public async Task<List<XieYiYiYuanChuKuOutput>> XieYiYiYuanChuKuList(XieYiYiYuanChuKuListInput input)
    {
        var orgCode = await _sysOrg.AsQueryable().Where(t => t.Id == input.ruKuYuanQuId).Select(t => t.Code).FirstAsync();
        var timeRange = DateTime.Now.AddDays(-7);
        var entityList = await _repInvOtherOutStorageMaster.AsQueryable()
            .Where(a => a.BillType == "InvProtOutStorage")
            .WhereIF(input.KaiShiShiJian.IsNullOrEmpty(), a => a.CreationTime >= timeRange)
            .WhereIF(!input.KaiShiShiJian.IsNullOrEmpty(), a => input.KaiShiShiJian >= a.CreationTime)
            .WhereIF(!input.JieShuShiJian.IsNullOrEmpty(), a => input.JieShuShiJian <= a.CreationTime)
            .WhereIF(input.DanHao.HasValue(), a => a.BillNo == input.DanHao)
            .WhereIF(!input.DanJuZhuangTai.IsNullOrEmpty(), a => a.BillStatus == input.DanJuZhuangTai)
            .InnerJoin<BasBloodSource>((master, source) => master.BasBloodSourceId == source.Id).WhereIF(orgCode.HasValue(), (master, source) => source.Code == orgCode)
            .Select((master, source) => new XieYiYiYuanChuKuOutput
            {
                creationTime = master.CreationTime,
                danHao = master.BillNo,
                danJuZhuangTai = master.BillStatus,
                faXueLeiXing = master.ProtOutStorageType,
                laiYuan = master.Source,
                remark = master.Remark,
                shenHeXinXi = master.AuditInfo,
                chuKuShiJian = master.AuditTime,
                chuKuYuanYin = master.Cause
            }).OrderByDescending(master => master.creationTime).ToListAsync();

        return entityList;
    }

    private static string GetDaLeiName(int? basXyzl)
    {
        if (basXyzl == null)
        {
            return string.Empty;
        }

        return basXyzl switch
        {
            0 => "全血",
            1 => "红细胞",
            2 => "血浆",
            3 => "血小板",
            4 => "冷沉淀",
            _ => basXyzl.ToString()
        };
    }

    //查询列表协议医院出库单据明细
    public async Task<XieYiYiYuanChuKuMessageOutput> XieYiYiYuanChuKuMingxi(XieYiYiYuanChuKuDanHaoInput input)
    {
        var orgCode = await _sysOrg.AsQueryable().Where(t => t.Id == input.ruKuYuanQuId).Select(t => t.Code).FirstAsync();

        var master = await _repInvOtherOutStorageMaster.AsQueryable().Where(a => a.BillNo == input.DanHao)
                .InnerJoin<BasBloodSource>((master, source) => master.BasBloodSourceId == source.Id).WhereIF(orgCode.HasValue(), (master, source) => source.Code == orgCode)
                .Select((master, source) => new XieYiYiYuanChuKuOutput
                {
                    creationTime = master.CreationTime,
                    danHao = master.BillNo,
                    danJuZhuangTai = master.BillStatus,
                    faXueLeiXing = master.ProtOutStorageType,
                    laiYuan = master.Source,
                    remark = master.Remark,
                    shenHeXinXi = master.AuditInfo
                }).FirstAsync();
        if (master == null)
        {
            return new XieYiYiYuanChuKuMessageOutput
            {
                master = master,
                mingXiList = new List<XieYiYiYuanChuKuMingXiOutput>()
            };
        }
        var btms2QuanBuMingXiList = await _repInvOtherOutStorageDetail.AsQueryable().Where(detail => detail.BillNo == input.DanHao)
                .InnerJoin<InvBloodInfo>((detail, invBlood) => detail.InvBloodInfoId == invBlood.Id)
                .InnerJoin<BasBloodProduct>((detail, invBlood, product) => invBlood.BasBloodProductId == product.Code)
                .InnerJoin<BasBloodVariety>((detail, invBlood, product, variety) => product.BasBloodVarietyId == variety.Id)
                .Select((detail, invBlood, product, variety) => new
                {
                    xianXueMa = invBlood.BloodDonationCode,
                    chanPinId = invBlood.BasBloodProductId,
                    mingCheng = product.Name,
                    abo = invBlood.ABO,
                    rhD = invBlood.RhD,
                    rongLiang = invBlood.Volume,
                    danWei = invBlood.Unit,
                    jiaGe = (decimal)invBlood.WarehousingPrice,
                    caiXueShiJian = invBlood.GatheringDate,
                    zhiBeiShiJian = invBlood.MakeDate,
                    shiXiaoShiJian = (DateTime)invBlood.EffectiveDate,
                    variety,
                    product
                }).ToListAsync();



        // 提取献血码和产品ID列表
        var xianXueMaList = btms2QuanBuMingXiList.Select(t => t.xianXueMa).ToList();
        var chanPinIdList = btms2QuanBuMingXiList.Select(t => t.chanPinId).ToList();
        // 获取已进入库存的血液列表
        var inKuCunList = await _kuCun.AsQueryable()
                         .Where(t => xianXueMaList.Contains(t.xianXueMa) && chanPinIdList.Contains(t.chanPinId))
                         .Select(t => new { t.xianXueMa, t.chanPinId })
                         .ToListAsync();
        // 过滤掉已经进入库存的血液
        var buZaiKuCunXueYeList = btms2QuanBuMingXiList.Where(t => !inKuCunList.Any(stock => stock.xianXueMa == t.xianXueMa && stock.chanPinId == t.chanPinId)).ToList();

        // 获取产品表中需要新增的产品信息和需要修改的产品信息
        var btms2ChanPinList = buZaiKuCunXueYeList.Select(t => new { t.product, t.variety }).ToList();

        if (buZaiKuCunXueYeList.Count > 0)
        {
            // 获取血液列表的产品码，用于获取产品信息
            var notInStockChanPinIdList = buZaiKuCunXueYeList.Select(t => t.chanPinId).ToList();
            var chanPinList = await _xueYeChanPin.AsQueryable().Where(t => notInStockChanPinIdList.Contains(t.Id)).ToListAsync();


            var addChanPinList = new List<BasXueYeChanPin>();
            var updateChanPinList = new List<BasXueYeChanPin>();
            foreach (var item in btms2ChanPinList)
            {
                var toUpdateChanPinItem = chanPinList.Where(t => t.Id == item.product.Code).FirstOrDefault();
                if (toUpdateChanPinItem != null)
                {
                    // 获取要更新的产品
                    toUpdateChanPinItem.mingCheng = item.product.Name;
                    toUpdateChanPinItem.pinZhongId = item.product.BasBloodVarietyId;
                    toUpdateChanPinItem.daLei = GetDaLeiName(item.variety.BasXyzl);
                    toUpdateChanPinItem.isEnabled = item.product.IsEnabled;
                    updateChanPinList.Add(toUpdateChanPinItem);
                }
                else if (addChanPinList.Find(t => t.Id == item.product.Code) == null)
                {
                    // 获取新增的产品
                    addChanPinList.Add(new BasXueYeChanPin
                    {
                        Id = item.product.Code,
                        mingCheng = item.product.Name,
                        daLei = GetDaLeiName(item.variety.BasXyzl),
                        pinZhongId = item.variety.Id,
                        xueYeChanPinFeiYongId = 0,
                        remark = "",
                        isEnabled = item.product.IsEnabled
                    });
                }
            }

            await _xueYeChanPin.InsertRangeAsync(addChanPinList);
            await _xueYeChanPin.UpdateRangeAsync(updateChanPinList);

            // 获取品种进行更新和新增
            var btms2PinZhongList = btms2QuanBuMingXiList.Select(t => t.variety).ToList();
            var pinZhongIdList = btms2PinZhongList.Select(t => Convert.ToInt64(t.Id)).ToList();
            // 获取在库品种，进行更新
            var zaiKuPinZhongList = await _xueYePinZhong.AsQueryable().Where(t => pinZhongIdList.Contains(t.Id)).ToListAsync();

            var addPinZhongList = new List<BasXueYePinZhong>();
            var updatePinZhonList = new List<BasXueYePinZhong>();
            foreach (var item in btms2PinZhongList)
            {
                var pinZhong = zaiKuPinZhongList.Where(t => t.Id == item.Id).FirstOrDefault();
                if (pinZhong != null)
                {
                    // 添加要更新的品种
                    pinZhong.mingCheng = item.Name;
                    pinZhong.danWei = item.Unit;
                    pinZhong.shiFouPeiXue = item.IsCrossMatch;
                    pinZhong.daLei = GetDaLeiName(item.BasXyzl);
                    pinZhong.zhuanHuanLv = (int)item.UnitRate;
                    pinZhong.shiFouDaLiangYongXue = item.IsQuantity;
                    pinZhong.youXiaoQiXiaoShiShu = item.ExpirationTime;
                    updatePinZhonList.Add(pinZhong);
                }
                else if (addPinZhongList.Find(t => t.Id == item.Id) == null)
                {
                    // 添加要新增的品种
                    addPinZhongList.Add(new BasXueYePinZhong
                    {
                        Id = item.Id,
                        mingCheng = item.Name,
                        danWei = item.Unit,
                        shiFouPeiXue = item.IsCrossMatch,
                        daLei = GetDaLeiName(item.BasXyzl),
                        zhuanHuanLv = (int)item.UnitRate,
                        shiFouDaLiangYongXue = item.IsQuantity,
                        youXiaoQiXiaoShiShu = item.ExpirationTime,
                        isEnabled = item.IsEnabled,
                    });
                }
            }

            await _xueYePinZhong.InsertRangeAsync(addPinZhongList);
            await _xueYePinZhong.UpdateRangeAsync(updatePinZhonList);

        }


        // 返回前端的内容
        var outList = buZaiKuCunXueYeList.Adapt<List<XieYiYiYuanChuKuMingXiOutput>>();

        foreach (var item in outList)
        {
            // 获取品种、大类
            var chanPinItem = btms2ChanPinList.FirstOrDefault(t => t.product.Code == item.chanPinId);
            if (chanPinItem != null)
            {
                item.pinZhongId = chanPinItem.variety.Id;
                item.daLei = GetDaLeiName(chanPinItem.variety.BasXyzl);
            }
        }

        return new XieYiYiYuanChuKuMessageOutput
        {
            master = master,
            mingXiList = outList
        };
    }


    /// <summary>
    /// 查询预警数据
    /// </summary>
    /// <returns></returns>

    [AllowAnonymous]
    public async Task<List<BasYueXueYuJingOutputAndYueXueLian>> CheckYuJingShuJu(CheckYuJingShuJuInput input)
    {
        if (!input.dingXueYiYuanId.IsNullOrEmpty()) { 
        
        input.dingXueYiYuanCode =_sysOrg.AsQueryable().First(a=>a.Id==input.dingXueYiYuanId).Code;

        }

        //得到全部出口血液数据
        var entityChuKuInv = await _repInvOtherOutStorageMaster.AsQueryable()
                       .Where(a => a.BillType == "InvProtOutStorage")
                       .Where(t => t.CreationTime != null && t.CreationTime.Value.Year == input.shiJian.Year && t.CreationTime.Value.Month == input.shiJian.Month && t.BillStatus == 3)
                       .InnerJoin<BasBloodSource>((zhuBiao, source) => zhuBiao.BasBloodSourceId == source.Id)
                       .WhereIF(!input.dingXueYiYuanCode.IsNullOrEmpty(), (zhuBiao, source) => source.Code == input.dingXueYiYuanCode)
                       .InnerJoin<InvOtherOutStorageDetail>((zhuBiao, source, mingXi) => zhuBiao.BillNo == mingXi.BillNo)
                       .InnerJoin<InvBloodInfo>((zhuBiao, source, mingXi, invBlood) => mingXi.InvBloodInfoId == invBlood.Id)
                       .InnerJoin<BasBloodProduct>((zhuBiao, source, mingXi, invBlood, product) => invBlood.BasBloodProductId == product.Code)
                       .InnerJoin<BasBloodVariety>((zhuBiao, source, mingXi, invBlood, product, variety) => product.BasBloodVarietyId == variety.Id)
                       .GroupBy((zhuBiao, source, mingXi, invBlood, product, variety) => new
                       {
                           source.Code,
                           invBlood.ABO,
                           variety.BasXyzl,
                           variety.Unit
                       }).Select((zhuBiao, source,  mingXi, invBlood, product, variety) => new ChuKuInvTongji
                       {
                           dingXueYiYuanCode = source.Code,
                           basXyzl = variety.BasXyzl,
                           unit = variety.Unit,
                           abo = invBlood.ABO,
                           volume = SqlFunc.AggregateSum(invBlood.Volume),

                       })
               .ToListAsync();

        //得到约血医院
        var dingXueYiYuanList = await _sysOrg.AsQueryable().Where(a => a.TenantId != 1300000000001)
            .WhereIF(!input.dingXueYiYuanCode.IsNullOrEmpty(), org => org.Code == input.dingXueYiYuanCode)
            .WhereIF(!input.dingXueYiYuanId.IsNullOrEmpty(), t => t.Id == input.dingXueYiYuanId).ToListAsync();

        var entityChuKuInvTongJi = entityChuKuInv.GroupBy(a => new
        {
            a.dingXueYiYuanCode,
            a.dingXueYiYuan,
            a.basXyzl,
        }).Select((e) => new BasYueXueYuJingOutputAndYueXueLian
        {
            dingXueYiYuanCode = e.Key.dingXueYiYuanCode,
            basXyzl = e.Key.basXyzl,
        }).ToList();

        foreach (var item in entityChuKuInvTongJi)
        {

            var entityChuKuInvDingXueYiYuan = entityChuKuInv.Where(t => t.dingXueYiYuanCode == item.dingXueYiYuanCode && t.basXyzl == item.basXyzl);
            var dingXueYiYuan = dingXueYiYuanList.Where(t => t.Code == item.dingXueYiYuanCode).FirstOrDefault();
            if (dingXueYiYuan != null)
            {
                item.dingXueYiYuanId = dingXueYiYuan.Id;
                item.dingXueYiYuan = dingXueYiYuan.Name;
            }
            item.chuKuLiangA = entityChuKuInvDingXueYiYuan.Where(a => a.abo == "A").Sum(e => e.volume);
            item.chuKuLiangB = entityChuKuInvDingXueYiYuan.Where(a => a.abo == "B").Sum(e => e.volume);
            item.chuKuLiangAB = entityChuKuInvDingXueYiYuan.Where(a => a.abo == "AB").Sum(e => e.volume);
            item.chuKuLiangO = entityChuKuInvDingXueYiYuan.Where(a => a.abo == "O").Sum(e => e.volume);
            item.daLei = GetDaLeiName(item.basXyzl);
        }

        List<BasYueXueYuJingOutputAndYueXueLian> entityYueXueTongJiList = new List<BasYueXueYuJingOutputAndYueXueLian>();

        //得到大类
        var xueYeDaLeiList = _basEnum.AsQueryable().Where(t => t.enumType == "XueYeDaLei").Select(a => a.code).ToList();
        //得到全部预警信息
        var entityYuJingTongJi = await _basYueXueYuJing.AsQueryable().WhereIF(!input.dingXueYiYuanId.IsNullOrEmpty(), t => t.dingXueYiYuanId == input.dingXueYiYuanId)
           .InnerJoin<SysOrg>((zhuBiao, org) => zhuBiao.dingXueYiYuanId == org.Id)
           .WhereIF(!input.dingXueYiYuanCode.IsNullOrEmpty(), (zhuBiao, org) => org.Code == input.dingXueYiYuanCode)
            .ToListAsync();
        //进行分类汇总
        foreach (var item in dingXueYiYuanList)
        {
            foreach (var daLei in xueYeDaLeiList)
            {
                var entityYuXueTenant = entityChuKuInvTongJi.Where(zhuBiao => zhuBiao.dingXueYiYuanId == item.Id && zhuBiao.daLei == daLei).FirstOrDefault();
                var entityYuJingTenant = entityYuJingTongJi.Where(t => t.dingXueYiYuanId == item.Id && t.daLei == daLei).FirstOrDefault();
                var yueXueTongJi = new BasYueXueYuJingOutputAndYueXueLian
                {
                    daLei = daLei,
                    dingXueYiYuanId = item.Id,
                    dingXueYiYuan = item.Name,
                    yuJingZhiA = null,
                    yuJingZhiAB = null,
                    yuJingZhiB = null,
                    yuJingZhiO = null,
                    chuKuLiangO = 0,
                    chuKuLiangA = 0,
                    chuKuLiangAB = 0,
                    chuKuLiangB = 0,
                };
                if (entityYuXueTenant != null)
                {
                    yueXueTongJi.chuKuLiangA = entityYuXueTenant.chuKuLiangA;
                    yueXueTongJi.chuKuLiangB = entityYuXueTenant.chuKuLiangB;
                    yueXueTongJi.chuKuLiangO = entityYuXueTenant.chuKuLiangO;
                    yueXueTongJi.chuKuLiangAB = entityYuXueTenant.chuKuLiangAB;
                }

                if (entityYuJingTenant != null)
                {

                    yueXueTongJi.yuJingZhiA = entityYuJingTenant.yuJingZhiA;
                    yueXueTongJi.yuJingZhiB = entityYuJingTenant.yuJingZhiB;
                    yueXueTongJi.yuJingZhiO = entityYuJingTenant.yuJingZhiO;
                    yueXueTongJi.yuJingZhiAB = entityYuJingTenant.yuJingZhiAB;
                }

                entityYueXueTongJiList.Add(yueXueTongJi);
            }
        }

        return entityYueXueTongJiList;
    }



}
